package com.hwadee.property.util;

import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.security.Key;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Component
public class JwtUtil {

    @Resource
    private TokenProperties properties;

    /**
     * 生成token
     * @param userId 需要生成 token 的键值对象 用户id
     * @param role 需要生成 token 的键值对象 用户角色
     * @return 生成的 token
     */
    public String generateToken(Long userId, Integer role) {
        long currentTimeMillis = System.currentTimeMillis();
        Date expirationDate = new Date(currentTimeMillis + properties.getExpire());
        Key key = Keys.hmacShaKeyFor(properties.getSecret().getBytes());

        Map<String, Object> claims = new HashMap<>();
        // System.out.println(userId);
        claims.put("userId", userId);
        claims.put("role", role); // 添加角色信息

        System.out.println("JWT Claims: " + claims);

        return Jwts.builder()
                .setClaims(claims)
                .setExpiration(expirationDate)
                .signWith(key, SignatureAlgorithm.HS256)
                .compact();
    }

    /**
     * 用来解析token，判定是否有效
     * @param token 需要被解析的 token
     */
    public void verifyToken(String token) {
        if (!StringUtils.hasText(token)) {
            throw new JwtException("未授权, token 为空");
        }
        try {
            Key key = Keys.hmacShaKeyFor(properties.getSecret().getBytes());
            Jwts.parserBuilder()
                    .setSigningKey(key)
                    .build()
                    .parseClaimsJws(token);
        } catch (ExpiredJwtException e) {
            throw new BusinessException(ErrorCodes.OUTDATED, "Token已过期");
        } catch (UnsupportedJwtException e) {
            throw new JwtException("Token格式不支持");
        } catch (MalformedJwtException e) {
            throw new JwtException("Token格式错误");
        } catch (JwtException e) {
            throw new JwtException("Token验证失败");
        }
    }

    /**
     * 获取 token 对应的对象
     * @param token 需要被分析的 token
     * @return 该 token 对应的对象
     */
    public Map<String, Object> getSubject(String token) {
        verifyToken(token);
        Key key = Keys.hmacShaKeyFor(properties.getSecret().getBytes());
        Claims claims = Jwts.parserBuilder()
                .setSigningKey(key)
                .build()
                .parseClaimsJws(token)
                .getBody();
        return new HashMap<>(claims); // 将 Claims 转换为 Map
    }

    /**
     * 根据 token 键值对获取用户id
     * @param token 需要被分析的 token
     * @return 用户id
     */
    public Long getUserId(String token) {
        if (StringUtils.isEmpty(token)) {
            throw new IllegalArgumentException("getUserId: Token 不能为空");
        }

        verifyToken(token);
        Map<String, Object> subject;
        try {
            subject = getSubject(token);
        } catch (JwtException e) {
            throw new IllegalArgumentException("Token 解析失败: " + e.getMessage());
        }

        if (subject == null || !subject.containsKey("userId")) {
            throw new IllegalArgumentException("Token 解析失败，用户信息不存在。当前token为：" + token);
        }

        try {
            Object userIdObj = subject.get("userId");
            if (userIdObj instanceof Number) {
                return ((Number) userIdObj).longValue(); // 确保转换为 Long
            } else {
                return Long.parseLong(userIdObj.toString());
            }
        } catch (Exception e) {
            throw new IllegalArgumentException("Token 解析失败，用户ID格式错误。当前ID为：" + subject.get("userId"));
        }
    }




    /**
     * 为获取用户 id 而进行的 token 获取操作
     * @return 用户id
     */
    public long getUserId() {
        ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = null;
        if (sra != null) {
            request = sra.getRequest();
        }
        String token = null;
        if (request != null) {
            token = request.getHeader(properties.getPrefixKey());
        }
        return getUserId(token);
    }

    public int getUserType(String token) {
        if (StringUtils.isEmpty(token)) {
            throw new IllegalArgumentException("getUserType: Token 不能为空");
        }

        verifyToken(token);

        Map<String, Object> subject;
        try {
            subject = getSubject(token);
        } catch (JwtException e) {
            throw new IllegalArgumentException("Token 解析失败: " + e.getMessage());
        }

        if (subject == null || !subject.containsKey("role")) {
            throw new IllegalArgumentException("Token 解析失败，用户信息不存在。当前token为：" + token);
        }

        try {
            Object userTypeObj = subject.get("role");
            if (userTypeObj instanceof Number) {
                return ((Number) userTypeObj).intValue(); // 确保转换为 Integer
            } else {
                return Integer.parseInt(userTypeObj.toString());
            }
        } catch (Exception e) {
            throw new IllegalArgumentException("Token 解析失败，用户角色错误。当前role为：" + subject.get("role"));
        }
    }
}
